package com.ruoyi.framework.aspectj;

import com.ruoyi.common.core.lang.UUID;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.framework.aspectj.lang.annotation.Ide;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.security.service.TokenService;
import net.bytebuddy.implementation.bytecode.Throw;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

/**
 * 接口幂等性的 -- 分布式锁实现
 */
@Aspect
@Component
public class ReqSubmitAspect {


    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private TokenService tokenService;

    @Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.Ide)")
    public void idePointCut() {
    }

    @Around("idePointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 使用分布式锁 机制-实现
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        Ide ide = method.getAnnotation(Ide.class);
        int lockSeconds = ide.lockTime();
        HttpServletRequest request = ServletUtils.getRequest();
//        String token =tokenService.getToken(request);
//        if(token.isEmpty()){
//            return joinPoint.proceed();
//        }
        String requestURI = request.getRequestURI();
        String key = getIdeKey(request.getRemoteHost()+requestURI, requestURI);
        String clientId = UUID.randomUUID().toString();
        Boolean lock=redisTemplate.opsForValue().setIfAbsent(""+request.getRemoteHost()+requestURI,clientId,lockSeconds,TimeUnit.MILLISECONDS);
        if (lock) {
            // 获取锁成功
            Object result;
            try {
//                 执行进程
                result = joinPoint.proceed();
            } finally {
                // 解锁
                redisTemplate.delete(request.getRemoteHost()+requestURI);
            }
            return result;
        } else {
            // 获取锁失败，认为是重复提交的请求
            System.out.println("活动太火爆");
            throw  new BaseException("活动太火爆请稍后再试!");
        }


    }

    private String getIdeKey(String token, String requestURI) {
        return token + requestURI;
    }
}
